TBB: authenticate BL3-x images and certificates
authorJuan Castillo <[email protected]>
Wed, 28 Jan 2015 16:46:57 +0000 (16:46 +0000)
committerDan Handley <[email protected]>
Wed, 28 Jan 2015 18:27:54 +0000 (18:27 +0000)
This patch adds support to authenticate the Trusted Key certificate
and the BL3-x certificates and images at BL2.

Change-Id: I69a8c13a14c8da8b75f93097d3a4576aed71c5dd

bl2/bl2_main.c
drivers/io/io_fip.c
plat/fvp/fvp_io_storage.c
plat/fvp/include/platform_def.h
plat/juno/include/platform_def.h
plat/juno/plat_io_storage.c

index b7e2cff4f9ae506b0a21b2af740762d3a8ea7ee7..29ca0a5abe03ad3675e6dfedd8c1519eb43294ce 100644 (file)
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
+#include <auth.h>
 #include <bl_common.h>
 #include <debug.h>
 #include <platform.h>
 #include <platform_def.h>
 #include "bl2_private.h"
 
+#if TRUSTED_BOARD_BOOT
+
+#ifdef BL32_BASE
+static int bl32_cert_error;
+#endif
+
+/*
+ * Load and authenticate the key and content certificates for a BL3-x image
+ *
+ * Parameters:
+ *   key_cert_blob: key certificate blob id (see auth.h)
+ *   key_cert_name: key certificate filename
+ *   cont_cert_blob: content certificate blob id (see auth.h)
+ *   cont_cert_name: content certificate filename
+ *   mem_layout: Trusted SRAM memory layout
+ *   load_addr: load the certificates at this address
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name,
+                         int cont_cert_blob, const char *cont_cert_name,
+                         meminfo_t *mem_layout, uint64_t load_addr)
+{
+       image_info_t image_info;
+       int err;
+
+       /* Load Key certificate */
+       image_info.h.version = VERSION_1;
+       err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL);
+       if (err) {
+               ERROR("Cannot load %s.\n", key_cert_name);
+               return err;
+       }
+
+       err = auth_verify_obj(key_cert_blob, image_info.image_base,
+                       image_info.image_size);
+       if (err) {
+               ERROR("Invalid key certificate %s.\n", key_cert_name);
+               return err;
+       }
+
+       /* Load Content certificate */
+       image_info.h.version = VERSION_1;
+       err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL);
+       if (err) {
+               ERROR("Cannot load %s.\n", cont_cert_name);
+               return err;
+       }
+
+       err = auth_verify_obj(cont_cert_blob, image_info.image_base,
+                       image_info.image_size);
+       if (err) {
+               ERROR("Invalid content certificate %s.\n", cont_cert_name);
+               return err;
+       }
+
+       return 0;
+}
+
+/*
+ * Load and authenticate the Trusted Key certificate the key and content
+ * certificates for each of the BL3-x images.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int load_certs(void)
+{
+       const uint64_t load_addr = BL31_BASE;
+       image_info_t image_info;
+       meminfo_t *mem_layout;
+       int err;
+
+       /* Find out how much free trusted ram remains after BL2 load */
+       mem_layout = bl2_plat_sec_mem_layout();
+
+       /* Load the Trusted Key certificate in the BL31 region */
+       image_info.h.version = VERSION_1;
+       err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr,
+                        &image_info, NULL);
+       if (err) {
+               ERROR("Failed to load Trusted Key certificate.\n");
+               return err;
+       }
+
+       /* Validate the certificate */
+       err = auth_verify_obj(AUTH_TRUSTED_KEY_CERT, image_info.image_base,
+                       image_info.image_size);
+       if (err) {
+               ERROR("Invalid Trusted Key certificate.\n");
+               return err;
+       }
+
+       /* Load and validate Key and Content certificates for BL3-x images */
+#ifdef BL30_BASE
+       err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME,
+                            AUTH_BL30_IMG_CERT, BL30_CERT_NAME,
+                            mem_layout, load_addr);
+       if (err) {
+               ERROR("Failed to verify BL3-0 authenticity\n");
+               return err;
+       }
+#endif /* BL30_BASE */
+
+       err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME,
+                            AUTH_BL31_IMG_CERT, BL31_CERT_NAME,
+                            mem_layout, load_addr);
+       if (err) {
+               ERROR("Failed to verify BL3-1 authenticity\n");
+               return err;
+       }
+
+#ifdef BL32_BASE
+       /* BL3-2 image is optional, but keep the return value in case the
+        * image is present but the certificate is missing */
+       err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME,
+                            AUTH_BL32_IMG_CERT, BL32_CERT_NAME,
+                            mem_layout, load_addr);
+       if (err) {
+               WARN("Failed to verify BL3-2 authenticity\n");
+       }
+       bl32_cert_error = err;
+#endif /* BL32_BASE */
+
+       err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME,
+                            AUTH_BL33_IMG_CERT, BL33_CERT_NAME,
+                            mem_layout, load_addr);
+       if (err) {
+               ERROR("Failed to verify BL3-3 authenticity\n");
+               return err;
+       }
+
+       return 0;
+}
+
+#endif /* TRUSTED_BOARD_BOOT */
+
 /*******************************************************************************
  * Load the BL3-0 image if there's one.
  * If a platform does not want to attempt to load BL3-0 image it must leave
@@ -69,6 +206,20 @@ static int load_bl30(void)
                       NULL);
 
        if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+               e = auth_verify_obj(AUTH_BL30_IMG,
+                               bl30_image_info.image_base,
+                               bl30_image_info.image_size);
+               if (e) {
+                       ERROR("Failed to authenticate BL3-0 image.\n");
+                       panic();
+               }
+
+               /* After working with data, invalidate the data cache */
+               inv_dcache_range(bl30_image_info.image_base,
+                                (size_t)bl30_image_info.image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
                /* The subsequent handling of BL3-0 is platform specific */
                bl2_plat_handle_bl30(&bl30_image_info);
        }
@@ -106,9 +257,24 @@ static int load_bl31(bl31_params_t *bl2_to_bl31_params,
                       bl2_to_bl31_params->bl31_image_info,
                       bl31_ep_info);
 
-       if (e == 0)
+       if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+               e = auth_verify_obj(AUTH_BL31_IMG,
+                       bl2_to_bl31_params->bl31_image_info->image_base,
+                       bl2_to_bl31_params->bl31_image_info->image_size);
+               if (e) {
+                       ERROR("Failed to authenticate BL3-1 image.\n");
+                       panic();
+               }
+
+               /* After working with data, invalidate the data cache */
+               inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base,
+                       (size_t)bl2_to_bl31_params->bl31_image_info->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
                bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
                                          bl31_ep_info);
+       }
 
        return e;
 }
@@ -144,6 +310,25 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params)
                       bl2_to_bl31_params->bl32_ep_info);
 
        if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+               /* Image is present. Check if there is a valid certificate */
+               if (bl32_cert_error) {
+                       ERROR("Failed to authenticate BL3-2 certificates.\n");
+                       panic();
+               }
+
+               e = auth_verify_obj(AUTH_BL32_IMG,
+                       bl2_to_bl31_params->bl32_image_info->image_base,
+                       bl2_to_bl31_params->bl32_image_info->image_size);
+               if (e) {
+                       ERROR("Failed to authenticate BL3-2 image.\n");
+                       panic();
+               }
+               /* After working with data, invalidate the data cache */
+               inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base,
+                       (size_t)bl2_to_bl31_params->bl32_image_info->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
                bl2_plat_set_bl32_ep_info(
                        bl2_to_bl31_params->bl32_image_info,
                        bl2_to_bl31_params->bl32_ep_info);
@@ -176,9 +361,23 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params)
                       bl2_to_bl31_params->bl33_image_info,
                       bl2_to_bl31_params->bl33_ep_info);
 
-       if (e == 0)
+       if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+               e = auth_verify_obj(AUTH_BL33_IMG,
+                               bl2_to_bl31_params->bl33_image_info->image_base,
+                               bl2_to_bl31_params->bl33_image_info->image_size);
+               if (e) {
+                       ERROR("Failed to authenticate BL3-3 image.\n");
+                       panic();
+               }
+               /* After working with data, invalidate the data cache */
+               inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base,
+                       (size_t)bl2_to_bl31_params->bl33_image_info->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
                bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
                                          bl2_to_bl31_params->bl33_ep_info);
+       }
 
        return e;
 }
@@ -200,6 +399,18 @@ void bl2_main(void)
        /* Perform remaining generic architectural setup in S-EL1 */
        bl2_arch_setup();
 
+#if TRUSTED_BOARD_BOOT
+       /* Initialize authentication module */
+       auth_init();
+
+       /* Validate the certificates involved in the Chain of Trust */
+       e = load_certs();
+       if (e) {
+               ERROR("Chain of Trust invalid. Aborting...\n");
+               panic();
+       }
+#endif /* TRUSTED_BOARD_BOOT */
+
        /*
         * Load the subsequent bootloader images
         */
index 7d2059076905b52153074f005acc82e38bdf4dff..0cec80448ee30ec6f3979ee55182ee861bbc143c 100644 (file)
@@ -79,6 +79,19 @@ static const plat_fip_name_uuid_t name_uuid[] = {
 #if TRUSTED_BOARD_BOOT
        /* Certificates */
        {BL2_CERT_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT},
+       {TRUSTED_KEY_CERT_NAME, UUID_TRUSTED_KEY_CERT},
+#ifdef BL30_KEY_CERT_NAME
+       {BL30_KEY_CERT_NAME, UUID_SCP_FIRMWARE_BL30_KEY_CERT},
+#endif
+       {BL31_KEY_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT},
+       {BL32_KEY_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_KEY_CERT},
+       {BL33_KEY_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT},
+#ifdef BL30_CERT_NAME
+       {BL30_CERT_NAME, UUID_SCP_FIRMWARE_BL30_CERT},
+#endif
+       {BL31_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT},
+       {BL32_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_CERT},
+       {BL33_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_CERT},
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
index b1e033ee46aba31fe51ce05fab18ae5188bad33b..ec1fe584c90f8908f06e1a79111f4641bd1cd755 100644 (file)
@@ -82,6 +82,51 @@ static const io_file_spec_t bl2_cert_file_spec = {
        .path = BL2_CERT_NAME,
        .mode = FOPEN_MODE_RB
 };
+
+static const io_file_spec_t trusted_key_cert_file_spec = {
+       .path = TRUSTED_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_key_cert_file_spec = {
+       .path = BL30_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_key_cert_file_spec = {
+       .path = BL31_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_key_cert_file_spec = {
+       .path = BL32_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_key_cert_file_spec = {
+       .path = BL33_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_cert_file_spec = {
+       .path = BL30_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_cert_file_spec = {
+       .path = BL31_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_cert_file_spec = {
+       .path = BL32_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_cert_file_spec = {
+       .path = BL33_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
 #endif /* TRUSTED_BOARD_BOOT */
 
 static int open_fip(const uintptr_t spec);
@@ -127,6 +172,51 @@ static const struct plat_io_policy policies[] = {
                (uintptr_t)&bl2_cert_file_spec,
                open_fip
        }, {
+               TRUSTED_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&trusted_key_cert_file_spec,
+               open_fip
+       }, {
+               BL30_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl30_key_cert_file_spec,
+               open_fip
+       }, {
+               BL31_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl31_key_cert_file_spec,
+               open_fip
+       }, {
+               BL32_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl32_key_cert_file_spec,
+               open_fip
+       }, {
+               BL33_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl33_key_cert_file_spec,
+               open_fip
+       }, {
+               BL30_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl30_cert_file_spec,
+               open_fip
+       }, {
+               BL31_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl31_cert_file_spec,
+               open_fip
+       }, {
+               BL32_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl32_cert_file_spec,
+               open_fip
+       }, {
+               BL33_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl33_cert_file_spec,
+               open_fip
+       }, {
 #endif /* TRUSTED_BOARD_BOOT */
                0, 0, 0
        }
index edbbdf31aa69021cd8e9ae1f0545097f988a4097..326ba9d981a4f5f6b127b3cc1b7d7cd7c6418ec8 100644 (file)
 #if TRUSTED_BOARD_BOOT
 /* Certificates */
 # define BL2_CERT_NAME                 "bl2.crt"
+# define TRUSTED_KEY_CERT_NAME         "trusted_key.crt"
+
+# define BL30_KEY_CERT_NAME            "bl30_key.crt"
+# define BL31_KEY_CERT_NAME            "bl31_key.crt"
+# define BL32_KEY_CERT_NAME            "bl32_key.crt"
+# define BL33_KEY_CERT_NAME            "bl33_key.crt"
+
+# define BL30_CERT_NAME                        "bl30.crt"
+# define BL31_CERT_NAME                        "bl31.crt"
+# define BL32_CERT_NAME                        "bl32.crt"
+# define BL33_CERT_NAME                        "bl33.crt"
 #endif /* TRUSTED_BOARD_BOOT */
 
 #define PLATFORM_CACHE_LINE_SIZE       64
index 748b32d9ff12d93dfc2dcab9fcaf8b2ae478a24a..1071d120538ec0f3088a6a95afc64351fc2434b0 100644 (file)
 #if TRUSTED_BOARD_BOOT
 /* Certificates */
 # define BL2_CERT_NAME                 "bl2.crt"
+# define TRUSTED_KEY_CERT_NAME         "trusted_key.crt"
+
+# define BL30_KEY_CERT_NAME            "bl30_key.crt"
+# define BL31_KEY_CERT_NAME            "bl31_key.crt"
+# define BL32_KEY_CERT_NAME            "bl32_key.crt"
+# define BL33_KEY_CERT_NAME            "bl33_key.crt"
+
+# define BL30_CERT_NAME                        "bl30.crt"
+# define BL31_CERT_NAME                        "bl31.crt"
+# define BL32_CERT_NAME                        "bl32.crt"
+# define BL33_CERT_NAME                        "bl33.crt"
 #endif /* TRUSTED_BOARD_BOOT */
 
 #define PLATFORM_CACHE_LINE_SIZE       64
index dd9f048af6c8b38188da3dae71cc28f373b15caa..b31865e44a6697fe0f74fb47b700a4392a385952 100644 (file)
@@ -82,6 +82,51 @@ static const io_file_spec_t bl2_cert_file_spec = {
        .path = BL2_CERT_NAME,
        .mode = FOPEN_MODE_RB
 };
+
+static const io_file_spec_t trusted_key_cert_file_spec = {
+       .path = TRUSTED_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_key_cert_file_spec = {
+       .path = BL30_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_key_cert_file_spec = {
+       .path = BL31_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_key_cert_file_spec = {
+       .path = BL32_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_key_cert_file_spec = {
+       .path = BL33_KEY_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_cert_file_spec = {
+       .path = BL30_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_cert_file_spec = {
+       .path = BL31_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_cert_file_spec = {
+       .path = BL32_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_cert_file_spec = {
+       .path = BL33_CERT_NAME,
+       .mode = FOPEN_MODE_RB
+};
 #endif /* TRUSTED_BOARD_BOOT */
 
 static int open_fip(const uintptr_t spec);
@@ -132,6 +177,51 @@ static const struct plat_io_policy policies[] = {
                (uintptr_t)&bl2_cert_file_spec,
                open_fip
        }, {
+               TRUSTED_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&trusted_key_cert_file_spec,
+               open_fip
+       }, {
+               BL30_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl30_key_cert_file_spec,
+               open_fip
+       }, {
+               BL31_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl31_key_cert_file_spec,
+               open_fip
+       }, {
+               BL32_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl32_key_cert_file_spec,
+               open_fip
+       }, {
+               BL33_KEY_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl33_key_cert_file_spec,
+               open_fip
+       }, {
+               BL30_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl30_cert_file_spec,
+               open_fip
+       }, {
+               BL31_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl31_cert_file_spec,
+               open_fip
+       }, {
+               BL32_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl32_cert_file_spec,
+               open_fip
+       }, {
+               BL33_CERT_NAME,
+               &fip_dev_handle,
+               (uintptr_t)&bl33_cert_file_spec,
+               open_fip
+       }, {
 #endif /* TRUSTED_BOARD_BOOT */
                0, 0, 0
        }